package cz.cuni.amis.pogamut.episodic.schemas;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;

/**
 * The class <code>SchemaObjectNode</code> is a mirror of <code>ObjectNode</code>s
 * from chronobag structure. There is exactly one <code>SchemaObjectNode</code>
 * created for each item that was ever used by an agent.
 * <p>
 * In schemas these nodes are linked together with slots they were used in
 * via the <code>SlotContent</code> structure. Thus it is possible to determine
 * how many times each item was used to perform each node.
 *
 * @author Michal Cermak
 */
public class SchemaObjectNode implements Serializable {
    /**
     * Determines if a de-serialized file is compatible with this class.
     *
     * Maintainers must change this value if and only if the new version
     * of this class is not compatible with old versions. See Sun docs
     * for <a href=http://java.sun.com/products/jdk/1.1/docs/guide
     * /serialization/spec/version.doc.html> details. </a>
     *
     * Not necessary to include in first version of the class, but
     * included here as a reminder of its importance.
     */
    private static final long serialVersionUID = 1L;

    /**
     * ID of this node. Used as an ID of vertex representing
     * this chronobag when visualizing Schemas.
     */
    final int id;

    /**
     * Unique name of the item this node is representing.
     */
    final String name;

    /**
     * In schemas these nodes are linked together with slots they were used in
     * via the <code>SlotContent</code> structure. Thus it is possible to
     * determine how many times each item was used to perform each node.
     * Each <code>SlotContent</code> is linking exactly one <code>SchemaSlot</code>
     * and one <code>SchemaObjectNode</code>.
     * <p>
     * This is the map of all <code>SlotContent</code>s pointing to this
     * <code>SchemaObjectNode</code> <strong>indexed by the ID of
     * the <code>SchemaSlot</code></strong> they linking the object with.
     */
    HashMap<Integer, SlotContent> usedIn = new HashMap<Integer, SlotContent>();

    /**
     * Instantiate the class by providing unique ID of the node and unique
     * name of item it is representing.
     *
     * @param   _id Unique ID of the new node.
     * @param   _name   Unique name of the item.
     */
    public SchemaObjectNode(int _id, String _name) {
        id = _id;
        name = _name;
    }

    /**
     * Getter method for the <code>id</code> variable.
     *
     * @return  Returns ID of this node. Used as an ID of vertex representing
     * this chronobag when visualizing Schemas.
     */
    public int getId() {
        return id;
    }
    /**
     * Getter method for the <code>name</code> variable.
     *
     * @return  Returns unique name of the item this node is representing.
     */
    public String getName() {
        return name;
    }

    /**
     * When the item represented by this node is used in an affordance slot,
     * it is linked with the node representing that slot via the <code>
     * SlotContent</code> class. This method adds a new <code>SlotContent</code>
     * to the list of slot contents that link this item to all the slots
     * it was ever used in. If however this item was already linked with that
     * slot, this method does nothing.
     * @param content   <code>SlotContent</code> object to be added to
     * the list of <code>SlotContent</code>s connecting this item node
     * with slot nodes.
     * @return  Returns true, if new link was created. Returns false if
     * the link between the item and the slot already existed in schema.
     */
    public boolean addSlotUsedIn(SlotContent content) {
        if (usedIn.containsKey(content.slot.id)) return false;
        usedIn.put(content.slot.id, content);
        return true;
    }
    /**
     * Basically a getter method for the <code>usedIn</code> variable.
     *
     * @return  Returns the map of all <code>SlotContent</code>s pointing to
     * this <code>SchemaObjectNode</code>.
     */
    public Collection<SlotContent> getSlotContents() {
        return usedIn.values();
    }
}
